using InventoryIssue.API.Write.Application.Command.Allocate;
using InventoryIssue.Domain;
using InventoryIssue.ErrorCode;
using InventoryIssue.Infrastructrue.Implement;
using MediatR;
using System;
using System.Linq;
using System.Collections.Generic;

namespace InventoryIssue.API.Write.Application.Handler.Allocate
{
    /// <summary>
    /// 更新调拨单处理器
    /// 负责处理库存调拨单的更新逻辑，包括主单和产品明细的修改
    /// </summary>
    public class UpdateAllocateStatusHandler : IRequestHandler<UpdateAllocateStatusCommand, APIResult<int>>
    {
        /// <summary>
        /// 数据库上下文，用于数据库操作
        /// </summary>
        private readonly DatabaseContext db;

        /// <summary>
        /// 构造函数，注入依赖项
        /// </summary>
        /// <param name="db">数据库上下文</param>
        public UpdateAllocateStatusHandler(DatabaseContext db)
        {
            this.db = db;
        }

        /// <summary>
        /// 处理更新调拨单命令
        /// </summary>
        /// <param name="request">更新调拨单命令对象</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>返回API结果，包含更新的记录数量</returns>
        public async Task<APIResult<int>> Handle(UpdateAllocateStatusCommand request, CancellationToken cancellationToken)
        {
            try
            {
                // 初始化返回结果
                APIResult<int> result = new APIResult<int>();

                // 自动补全AllocateId前导0，长度为6
                if (!string.IsNullOrEmpty(request.AllocateId))
                    request.AllocateId = request.AllocateId.PadLeft(6, '0');

                // 查询调拨单信息
                var allocate = await db.SqlSugar.Queryable<AllocateModel>()
                    .Where(x => x.AllocateId == request.AllocateId )
                    .FirstAsync();

                // 验证调拨单是否存在
                if (allocate == null)
                {
                    result.Message = $"未找到调拨单，AllocateId: {request.AllocateId}";
                    result.Code = APIEnum.Fail;
                    return result;
                }

                // 开始数据库事务
                await db.SqlSugar.Ado.BeginTranAsync();

                // 更新主表字段 - 只允许编辑非主键字段
                // allocate.AllocateId = request.AllocateId; // 禁止编辑主键字段
                if (!string.IsNullOrEmpty(request.OrderNumber))
                    allocate.OrderNumber = request.OrderNumber;
                if (!string.IsNullOrEmpty(request.AllocateWarehouseIn))
                    allocate.AllocateWarehouseIn = request.AllocateWarehouseIn;
                if (!string.IsNullOrEmpty(request.AllocateWarehouseOut))
                    allocate.AllocateWarehouseOut = request.AllocateWarehouseOut;
                if (!string.IsNullOrEmpty(request.OrderCreator))
                    allocate.OrderCreator = request.OrderCreator;
                if (!string.IsNullOrEmpty(request.Note))
                    allocate.Note = request.Note;
                if (request.State >= 0)
                    allocate.State = request.State;
                if (request.OrderCreatorTime > DateTime.MinValue)
                    allocate.OrderCreatorTime = request.OrderCreatorTime;
                if (!string.IsNullOrEmpty(request.Manager))
                    allocate.Manager = request.Manager;
                if (request.ManagerTime.HasValue)
                    allocate.ManagerTime = request.ManagerTime;

                // 更新主表记录
                int mainUpdateCount = await db.SqlSugar.Updateable(allocate)
                    .Where(x => x.AllocateId == request.AllocateId)
                    .ExecuteCommandAsync();

                // 逻辑删除原有产品明细（全量覆盖风格）
                var oldProducts = await db.SqlSugar.Queryable<AllocateProductModel>()
                    .Where(x => x.AllocateId == allocate.AllocateId && !x.IsDel)
                    .ToListAsync();
                foreach (var item in oldProducts)
                    item.IsDel = true;
                if (oldProducts.Count > 0)
                    await db.SqlSugar.Updateable(oldProducts).WhereColumns(x => x.Id).ExecuteCommandAsync();

                // 创建新的产品明细列表
                var newProducts = request.Products.Select(p => new AllocateProductModel
                {
                    AllocateId = allocate.AllocateId,
                    ProductId = p.ProductId,
                    Quantity = p.Quantity,
                    CreateTime = DateTime.Now,
                    IsDel = false
                }).ToList();

                // 批量插入新的产品明细
                int productCount = 0;
                if (newProducts.Count > 0)
                    productCount = await db.SqlSugar.Insertable(newProducts).ExecuteCommandAsync();

                //增加操作记录
                OperationLog log = new OperationLog()
                {
                    Operator = request.OrderCreator,
                    AllocateId = request.AllocateId,
                    OperationType = "修改",
                    OperationContent = request.Note,
                    CreateTime = DateTime.Now,
                    IsDel = false
                };
                await db.SqlSugar.Insertable(log).ExecuteReturnIdentityAsync();

                // 提交事务
                await db.SqlSugar.Ado.CommitTranAsync();

                // 设置成功返回结果
                result.Message = "编辑成功";
                result.Code = APIEnum.Ok;
                result.Data = mainUpdateCount + productCount;
                return result;
            }
            catch (Exception ex)
            {
                // 发生异常时回滚事务
                await db.SqlSugar.Ado.RollbackTranAsync();
                
                // 设置失败返回结果
                APIResult<int> result = new APIResult<int>();
                result.Code = APIEnum.Fail;
                result.Message = "修改失败：" + ex.Message;
                return result;
            }
        }
    }
}